package com.chenfan.process.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chenfan.ccp.common.exception.ApiException;
import com.chenfan.process.common.constants.ProcessConstants;
import com.chenfan.process.common.exception.ProcessResultCode;
import com.chenfan.process.entity.dto.ApprovalTemplateDTO;
import com.chenfan.process.entity.dto.InstanceSnapshotDTO;
import com.chenfan.process.entity.po.ProcessPo;
import com.chenfan.process.entity.po.ProcessRelatedPo;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2021/9/29
 */
public class NodeUtil {

    public static boolean validateSubmit(String processId) {
        if (StringUtils.isEmpty(processId)) {
            return false;
        }
        return !Objects.equals(ProcessConstants.DEFAULT_SKIP_CHECK_PERMISSION_USER_ID, processId);
    }

    public static Long getNode(Map<Long, ProcessPo> processMap, String relation, Long userId) {
        InstanceSnapshotDTO instanceSnapshot = JSONObject.parseObject(relation, InstanceSnapshotDTO.class);
        List<ProcessRelatedPo> processRelated = instanceSnapshot.getProcessRelatedPoList();
        for (ProcessRelatedPo related : processRelated) {
            ProcessPo processPo = processMap.get(related.getProcessAfterId());
            String associateGroupId = processPo.getAssociateGroupId();
            if (Objects.equals(associateGroupId, userId.toString())) {
                return processPo.getId();
            }
        }
        return null;
    }

    public static List<Long> getNodes(String relation, Long userId) {
        InstanceSnapshotDTO instanceSnapshot = JSONObject.parseObject(relation, InstanceSnapshotDTO.class);
        List<ProcessPo> processList = instanceSnapshot.getProcessList();
        Map<Long, ProcessPo> processMap = processList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        List<ProcessRelatedPo> relations = instanceSnapshot.getProcessRelatedPoList();
        List<Long> processIdList = new ArrayList<>();
        for (ProcessRelatedPo related : relations) {
            ProcessPo processPo = processMap.get(related.getProcessAfterId());
            String associateGroupId = processPo.getAssociateGroupId();
            if (Objects.equals(associateGroupId, userId.toString())) {
                processIdList.add(processPo.getId());
            }
        }
        return processIdList;
    }

    public static List<Long> getNodes(Map<Long, ProcessPo> processMap, String relation, Long userId) {
        List<ProcessRelatedPo> relations = JSONArray.parseArray(relation, ProcessRelatedPo.class);
        List<Long> processIdList = new ArrayList<>();
        for (ProcessRelatedPo related : relations) {
            ProcessPo processPo = processMap.get(related.getProcessAfterId());
            String associateGroupId = processPo.getAssociateGroupId();
            if (Objects.equals(associateGroupId, userId.toString())) {
                processIdList.add(processPo.getId());
            }
        }
        return processIdList;
    }

    public static void validateData(List<ApprovalTemplateDTO.LinkData> linkDataArray,
                              List<ApprovalTemplateDTO.NodeData> nodeDataArray) {
//        Assert.notEmpty(nodeDataArray, );
//        Assert.notEmpty(linkDataArray, );
        if (CollectionUtils.isEmpty(nodeDataArray)) {
            throw new ApiException(ProcessResultCode.NODE_DATA_NOT_NULL);
        }
        if (CollectionUtils.isEmpty(linkDataArray)) {
            throw new ApiException(ProcessResultCode.LINK_DATA_NOT_NULL);
        }

        linkDataArray.forEach(e -> {
            List<List<ApprovalTemplateDTO.LinkDataAttribute>> attributes = e.getAttributes();
            // 对attribute中的元素进行排序
            if(Objects.nonNull(attributes)){
                attributes.forEach(x -> x.sort(Comparator.comparing(ApprovalTemplateDTO.LinkDataAttribute::getFormAttributeId)));
                // 在对attributes本身进行排序
                attributes.sort(Comparator.comparing(o ->
                        CollectionUtils.isEmpty(o) ? "0" : o.get(0).getFormAttributeId()
                ));
            }
        });

        // 最后进行去重操作
        List<ApprovalTemplateDTO.LinkData> linkData = linkDataArray.stream().filter(e -> {
            List<List<ApprovalTemplateDTO.LinkDataAttribute>> attributes = e.getAttributes();
            return  !CollectionUtils.isEmpty(attributes) && attributes.stream().noneMatch(CollectionUtils::isEmpty) ;
        }).collect(Collectors.toList());

        Map<Long,List<ApprovalTemplateDTO.LinkData>> linkDataGroup = linkData.stream().collect(Collectors.groupingBy(ApprovalTemplateDTO.LinkData::getFrom));

        linkDataGroup.forEach((key,value) ->{
            Set<ApprovalTemplateDTO.LinkData> hashSet = new HashSet<>(value);
            if (value.size() != hashSet.size()) {
                throw new ApiException(ProcessResultCode.SAME_BRANCH_EXISTS);
            }
        });
    }
}
